// ignore_for_file: file_names

import 'package:dio/dio.dart';
import 'package:flutter_house_manager/constants/index.dart';
import 'package:flutter_house_manager/utils/Emitter.dart';
import 'package:flutter_house_manager/utils/TokenManager.dart';

class RequestDio {
  final _dio = Dio();
  // 1. 主构造函数
  RequestDio() {
    // 正常写法:
    // 基础地址
    // _dio.options.baseUrl = GlobalVariable.BASE_URL;
    // 连接超时时间
    // _dio.options.connectTimeout = const Duration(seconds: GlobalVariable.NEW_WORK_TIME_OUT);
    // 接收超时时间
    // _dio.options.receiveTimeout = const Duration(seconds: GlobalVariable.NEW_WORK_TIME_OUT);

    // 链式写法:
    _dio.options
      ..baseUrl = GlobalVariable.BASE_URL
      ..connectTimeout =
          const Duration(seconds: GlobalVariable.NEW_WORK_TIME_OUT)
      ..receiveTimeout =
          const Duration(seconds: GlobalVariable.NEW_WORK_TIME_OUT);

    // 添加拦截器
    _dio.interceptors.add(InterceptorsWrapper(onRequest: (context, handler) {
      // 请求拦截器
      // 注入token
      String token = tokenManager.getToken();
      if (token.isNotEmpty) {
        context.headers["Authorization"] = 'Bearer $token';
      }
      handler.next(context);
    }, onResponse: (context, handler) {
      // 2xx才是成功
      //http状态码
      if (context.statusCode! >= 200 && context.statusCode! <= 300) {
        // 响应拦截器
        handler.next(context); // 成功
      } else {
        // 说明 Promise pending fullfiled rejected
        handler
            .reject(DioException(requestOptions: context.requestOptions)); // 失败
      }
    },
        // 错误拦截器
        onError: (context, handler) async {
      if (context.response!.statusCode == 401) {
        // 跳转到登录页
        // Navigator.pushNamed(context, "/login");
        String refreshToken = tokenManager.getRefreshToken();
        if (refreshToken.isNotEmpty) {
          // 说明token过期了
          // 跳转到登录页
          try {
            await _refresh();
            return handler.resolve(await _dio.fetch(context.requestOptions));
          } on Exception catch (e) {
            emitter.fire(LogoutEvent(e.toString()));
          }
        } else {
          // 换取token
          // 发布订阅 触发一个事件 别人监听一个事件
          // emitter eventHub
          emitter.fire(LogoutEvent('401 未授权'));
        }
      }
      handler.reject(context);
    }));
  }

  /// 调用接口去刷新token
  _refresh() async {
    // 1. 获取refreshToken
    String refreshToken = tokenManager.getRefreshToken();
    // 2. 发起请求
    Dio newDio = Dio();
    final res = await newDio.post(
      '${GlobalVariable.BASE_URL}${HTTP_PATH.REFRESH_TOKEN}',
      options: Options(
        headers: {
          'Authorization': 'Bearer $refreshToken',
        },
      ),
    );
    // 3. 存储新的token
    tokenManager.setToken(res.data['data']['token'],
        refreshToken: res.data['data']['refreshToken']);
  }

  // 2. 定义方法
  get(String url, {Map<String, dynamic>? params}) {
    return _handleRes(_dio.get(url, queryParameters: params));
  }

  post(String url, {Map<String, dynamic>? data}) {
    return _handleRes(_dio.post(url, data: data));
  }

  put(String url, {Map<String, dynamic>? data}) {
    return _handleRes(_dio.put(url, data: data));
  }

  delete(String url,
      {Map<String, dynamic>? params, Map<String, dynamic>? data}) {
    return _handleRes(_dio.delete(url, queryParameters: params, data: data));
  }

  upload(String url, {FormData? data}) {
    return _handleRes(_dio.post(url, data: data));
  }

  // 数据剥离
  _handleRes(Future<Response<dynamic>> task) async {
    final res = await task;
    if (res.data['code'] == GlobalVariable.SUCCESS_CODE) {
      return res.data['data'];
    }
    // 错误处理
    throw DioException(requestOptions: res.requestOptions);
  }
}

final RequestDio requestDio = RequestDio();


// requestDio.get('/user/info', params: { 'id': 1})
// requestDio.post('/user/info', data: { 'id': 1})
// requestDio.put('/user/info', data: { 'id': 1})
// requestDio.delete('/user/info', params: { 'id': 1}, data: { 'id': 1})